package buaa.qel.rpc.server.core;

import buaa.qel.rpc.common.codec.RpcMessageCodec;
import buaa.qel.rpc.common.message.Beat;
import buaa.qel.rpc.common.protocol.RpcProtocolFrameDecoder;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class RpcServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    private Map<String, Object> serviceMap;
    private ThreadPoolExecutor threadPoolExecutor;
    LoggingHandler LOGGING_HANDLER = new LoggingHandler(LogLevel.DEBUG);
    RpcMessageCodec MESSAGE_CODEC = new RpcMessageCodec();

    /**
     * 问题记录：成员变量的主动初始化会在任何方法执行之前（包括构造方法）
     * 所以当成员变量初始化需要的参数由该对象的构造方法接收或初始化。
     * @param serviceMap
     * @param threadPoolExecutor
     */
    //RpcRequestHandler RPC_HANDLER = new RpcRequestHandler(serviceMap, threadPoolExecutor);

    public RpcServerChannelInitializer(Map<String, Object> serviceMap, ThreadPoolExecutor threadPoolExecutor) {
        this.serviceMap = serviceMap;
        this.threadPoolExecutor = threadPoolExecutor;
    }

    @Override
    public void initChannel(SocketChannel channel) throws Exception {
        ChannelPipeline cp = channel.pipeline();
        cp.addLast(new IdleStateHandler(0, 0, Beat.BEAT_TIMEOUT, TimeUnit.SECONDS));
        cp.addLast(new RpcProtocolFrameDecoder());
        cp.addLast(LOGGING_HANDLER);
        cp.addLast(MESSAGE_CODEC);
        cp.addLast(new RpcRequestHandler(serviceMap, threadPoolExecutor));
    }
}
